/**
 * 用户管理控制器
 * 处理所有与用户相关的HTTP请求，包括用户的CRUD操作、密码管理、个人信息更新等
 */
package cc.mrbird.febs.system.controller;

import cc.mrbird.febs.common.annotation.Log;
import cc.mrbird.febs.common.controller.BaseController;
import cc.mrbird.febs.common.domain.QueryRequest;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.utils.MD5Util;
import cc.mrbird.febs.system.domain.User;
import cc.mrbird.febs.system.domain.UserConfig;
import cc.mrbird.febs.system.service.UserConfigService;
import cc.mrbird.febs.system.service.UserService;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.wuwenze.poi.ExcelKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;

/**
 * @Slf4j: 启用日志功能
 * @Validated: 启用参数校验
 * @RestController: 标识这是一个REST风格的控制器
 * @RequestMapping("user"): 指定该控制器的基础URL路径为/user
 */
@Slf4j
@Validated
@RestController
@RequestMapping("user")
public class UserController extends BaseController {

    private String message;

    @Autowired
    private UserService userService;
    @Autowired
    private UserConfigService userConfigService;

    /**
     * 检查用户名是否已存在
     * @param username 要检查的用户名
     * @return true表示用户名可用，false表示用户名已存在
     */
    @GetMapping("check/{username}")
    public boolean checkUserName(@NotBlank(message = "{required}") @PathVariable String username) {
        return this.userService.findByName(username) == null;
    }

    /**
     * 获取用户详细信息
     * @param username 用户名
     * @return 用户对象
     */
    @GetMapping("/{username}")
    public User detail(@NotBlank(message = "{required}") @PathVariable String username) {
        return this.userService.findByName(username);
    }

    /**
     * 获取用户列表
     * @param queryRequest 查询请求参数
     * @param user 用户查询条件
     * @return 包含用户列表的数据表格
     */
    @GetMapping
    public Map<String, Object> userList(QueryRequest queryRequest, User user) {
        return getDataTable(userService.findUserDetail(user, queryRequest));
    }

    /**
     * 新增用户
     * @param user 用户信息
     * @throws FebsException 当添加用户失败时抛出异常
     */
    @Log("新增用户")
    @PostMapping
    public void addUser(@Valid User user) throws FebsException {
        try {
            this.userService.createUser(user);
        } catch (Exception e) {
            message = "新增用户失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 修改用户信息
     * @param user 用户信息
     * @throws FebsException 当修改用户失败时抛出异常
     */
    @Log("修改用户")
    @PutMapping
    @RequiresPermissions("user:update")
    public void updateUser(@Valid User user) throws FebsException {
        try {
            this.userService.updateUser(user);
        } catch (Exception e) {
            message = "修改用户失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 删除用户
     * @param userIds 要删除的用户ID，多个ID用逗号分隔
     * @throws FebsException 当删除用户失败时抛出异常
     */
    @Log("删除用户")
    @DeleteMapping("/{userIds}")
    @RequiresPermissions("user:delete")
    public void deleteUsers(@NotBlank(message = "{required}") @PathVariable String userIds) throws FebsException {
        try {
            String[] ids = userIds.split(StringPool.COMMA);
            this.userService.deleteUsers(ids);
        } catch (Exception e) {
            message = "删除用户失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 更新用户个人信息
     * @param user 用户信息
     * @throws FebsException 当更新个人信息失败时抛出异常
     */
    @PutMapping("profile")
    public void updateProfile(@Valid User user) throws FebsException {
        try {
            this.userService.updateProfile(user);
        } catch (Exception e) {
            message = "修改个人信息失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 更新用户头像
     * @param username 用户名
     * @param avatar 头像数据
     * @throws FebsException 当更新头像失败时抛出异常
     */
    @PutMapping("avatar")
    public void updateAvatar(
            @NotBlank(message = "{required}") String username,
            @NotBlank(message = "{required}") String avatar) throws FebsException {
        try {
            this.userService.updateAvatar(username, avatar);
        } catch (Exception e) {
            message = "修改头像失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 更新用户配置
     * @param userConfig 用户配置信息
     * @throws FebsException 当更新配置失败时抛出异常
     */
    @PutMapping("userconfig")
    public void updateUserConfig(@Valid UserConfig userConfig) throws FebsException {
        try {
            this.userConfigService.update(userConfig);
        } catch (Exception e) {
            message = "修改个性化配置失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 检查用户密码是否正确
     * @param username 用户名
     * @param password 密码
     * @return true表示密码正确，false表示密码错误
     */
    @GetMapping("password/check")
    public boolean checkPassword(
            @NotBlank(message = "{required}") String username,
            @NotBlank(message = "{required}") String password) {
        String encryptPassword = MD5Util.encrypt(username, password);
        User user = userService.findByName(username);
        if (user != null)
            return StringUtils.equals(user.getPassword(), encryptPassword);
        else
            return false;
    }

    /**
     * 修改用户密码
     * @param username 用户名
     * @param password 新密码
     * @throws FebsException 当修改密码失败时抛出异常
     */
    @PutMapping("password")
    public void updatePassword(
            @NotBlank(message = "{required}") String username,
            @NotBlank(message = "{required}") String password) throws FebsException {
        try {
            userService.updatePassword(username, password);
        } catch (Exception e) {
            message = "修改密码失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 重置用户密码
     * @param usernames 要重置密码的用户名列表，多个用户名用逗号分隔
     * @throws FebsException 当重置密码失败时抛出异常
     */
    @PutMapping("password/reset")
    @RequiresPermissions("user:reset")
    public void resetPassword(@NotBlank(message = "{required}") String usernames) throws FebsException {
        try {
            String[] usernameArr = usernames.split(StringPool.COMMA);
            this.userService.resetPassword(usernameArr);
        } catch (Exception e) {
            message = "重置用户密码失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 导出用户数据到Excel
     * @param queryRequest 查询请求参数
     * @param user 用户查询条件
     * @param response HTTP响应对象
     * @throws FebsException 当导出失败时抛出异常
     */
    @PostMapping("excel")
    @RequiresPermissions("user:export")
    public void export(QueryRequest queryRequest, User user, HttpServletResponse response) throws FebsException {
        try {
            List<User> users = this.userService.findUserDetail(user, queryRequest).getRecords();
            ExcelKit.$Export(User.class, response).downXlsx(users, false);
        } catch (Exception e) {
            message = "导出Excel失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }
}
